"""
指标卡片组件
提供各种指标展示的卡片组件
"""

import streamlit as st
from typing import Optional, Union
import plotly.graph_objects as go
from datetime import datetime


class MetricsCard:
    """指标卡片组件"""
    
    def __init__(
        self,
        title: str,
        value: Union[str, int, float],
        delta: Optional[str] = None,
        delta_color: str = "normal",
        help_text: Optional[str] = None
    ):
        """
        初始化指标卡片
        
        Args:
            title: 指标标题
            value: 指标值
            delta: 变化值或描述
            delta_color: 变化颜色 (normal, inverse, off)
            help_text: 帮助文本
        """
        self.title = title
        self.value = value
        self.delta = delta
        self.delta_color = delta_color
        self.help_text = help_text
        self.render()
    
    def render(self):
        """渲染指标卡片"""
        st.metric(
            label=self.title,
            value=self.value,
            delta=self.delta,
            delta_color=self.delta_color,
            help=self.help_text
        )


def create_kpi_card(
    title: str,
    value: Union[str, int, float],
    target: Optional[Union[int, float]] = None,
    format_func: Optional[callable] = None,
    color: str = "#1f77b4"
):
    """
    创建KPI指标卡片
    
    Args:
        title: 指标标题
        value: 当前值
        target: 目标值
        format_func: 格式化函数
        color: 颜色
    """
    if format_func:
        formatted_value = format_func(value)
        if target:
            formatted_target = format_func(target)
        else:
            formatted_target = None
    else:
        formatted_value = str(value)
        formatted_target = str(target) if target else None
    
    # 计算完成率
    completion_rate = None
    if target and target != 0:
        completion_rate = (value / target) * 100
    
    col1, col2 = st.columns([3, 1])
    
    with col1:
        st.markdown(f"**{title}**")
        st.markdown(f"<h2 style='color: {color}; margin: 0;'>{formatted_value}</h2>", 
                   unsafe_allow_html=True)
        
        if formatted_target:
            st.markdown(f"目标: {formatted_target}")
        
        if completion_rate:
            if completion_rate >= 100:
                st.success(f"完成率: {completion_rate:.1f}%")
            elif completion_rate >= 80:
                st.warning(f"完成率: {completion_rate:.1f}%")
            else:
                st.error(f"完成率: {completion_rate:.1f}%")
    
    with col2:
        if completion_rate:
            # 创建圆形进度条
            fig = go.Figure(go.Indicator(
                mode="gauge+number",
                value=completion_rate,
                domain={'x': [0, 1], 'y': [0, 1]},
                title={'text': "完成率"},
                gauge={
                    'axis': {'range': [None, 100]},
                    'bar': {'color': color},
                    'steps': [
                        {'range': [0, 50], 'color': "lightgray"},
                        {'range': [50, 80], 'color': "yellow"},
                        {'range': [80, 100], 'color': "lightgreen"}
                    ],
                    'threshold': {
                        'line': {'color': "red", 'width': 4},
                        'thickness': 0.75,
                        'value': 90
                    }
                }
            ))
            
            fig.update_layout(
                height=150,
                margin=dict(l=20, r=20, t=40, b=20),
                font={'size': 10}
            )
            
            st.plotly_chart(fig, use_container_width=True)


def create_trend_card(
    title: str,
    current_value: Union[int, float],
    previous_value: Union[int, float],
    format_func: Optional[callable] = None,
    reverse_colors: bool = False
):
    """
    创建趋势指标卡片
    
    Args:
        title: 指标标题
        current_value: 当前值
        previous_value: 之前值
        format_func: 格式化函数
        reverse_colors: 是否反转颜色（用于成本等指标）
    """
    if format_func:
        formatted_current = format_func(current_value)
        formatted_previous = format_func(previous_value)
    else:
        formatted_current = str(current_value)
        formatted_previous = str(previous_value)
    
    # 计算变化
    if previous_value != 0:
        change_percent = ((current_value - previous_value) / previous_value) * 100
        change_value = current_value - previous_value
    else:
        change_percent = 0
        change_value = current_value
    
    # 确定颜色
    if change_percent > 0:
        color = "red" if reverse_colors else "green"
        arrow = "↗️"
    elif change_percent < 0:
        color = "green" if reverse_colors else "red"
        arrow = "↘️"
    else:
        color = "gray"
        arrow = "➡️"
    
    st.markdown(f"**{title}**")
    
    col1, col2 = st.columns([2, 1])
    
    with col1:
        st.markdown(f"<h3 style='margin: 0;'>{formatted_current}</h3>", 
                   unsafe_allow_html=True)
        
        if format_func:
            change_text = format_func(abs(change_value))
        else:
            change_text = str(abs(change_value))
        
        st.markdown(
            f"<span style='color: {color};'>{arrow} {change_text} ({change_percent:+.1f}%)</span>",
            unsafe_allow_html=True
        )
    
    with col2:
        st.markdown(f"**上期**")
        st.markdown(formatted_previous)


def create_status_card(
    title: str,
    status: str,
    description: Optional[str] = None,
    last_update: Optional[datetime] = None
):
    """
    创建状态指标卡片
    
    Args:
        title: 标题
        status: 状态 (success, warning, error, info)
        description: 描述
        last_update: 最后更新时间
    """
    # 状态配置
    status_config = {
        "success": {"color": "#28a745", "icon": "✅", "text": "正常"},
        "warning": {"color": "#ffc107", "icon": "⚠️", "text": "警告"},
        "error": {"color": "#dc3545", "icon": "❌", "text": "错误"},
        "info": {"color": "#17a2b8", "icon": "ℹ️", "text": "信息"}
    }
    
    config = status_config.get(status, status_config["info"])
    
    st.markdown(f"**{title}**")
    
    col1, col2 = st.columns([3, 1])
    
    with col1:
        st.markdown(
            f"<h3 style='color: {config['color']}; margin: 0;'>"
            f"{config['icon']} {config['text']}</h3>",
            unsafe_allow_html=True
        )
        
        if description:
            st.markdown(description)
        
        if last_update:
            st.markdown(f"*更新时间: {last_update.strftime('%H:%M:%S')}*")
    
    with col2:
        # 状态指示器
        fig = go.Figure(go.Indicator(
            mode="gauge",
            value=1 if status == "success" else 0,
            domain={'x': [0, 1], 'y': [0, 1]},
            gauge={
                'axis': {'range': [None, 1], 'visible': False},
                'bar': {'color': config['color']},
                'bgcolor': "white",
                'borderwidth': 2,
                'bordercolor': config['color']
            }
        ))
        
        fig.update_layout(
            height=100,
            margin=dict(l=10, r=10, t=10, b=10),
            showlegend=False
        )
        
        st.plotly_chart(fig, use_container_width=True)


def create_comparison_card(
    title: str,
    values: dict,
    colors: Optional[dict] = None
):
    """
    创建对比指标卡片
    
    Args:
        title: 标题
        values: 值字典 {label: value}
        colors: 颜色字典 {label: color}
    """
    default_colors = ["#1f77b4", "#ff7f0e", "#2ca02c", "#d62728", "#9467bd"]
    
    st.markdown(f"**{title}**")
    
    # 创建饼图
    labels = list(values.keys())
    vals = list(values.values())
    
    if colors:
        chart_colors = [colors.get(label, default_colors[i % len(default_colors)]) 
                       for i, label in enumerate(labels)]
    else:
        chart_colors = default_colors[:len(labels)]
    
    fig = go.Figure(data=[go.Pie(
        labels=labels,
        values=vals,
        hole=0.4,
        marker_colors=chart_colors
    )])
    
    fig.update_layout(
        height=200,
        margin=dict(l=20, r=20, t=20, b=20),
        showlegend=True,
        legend=dict(
            orientation="h",
            yanchor="bottom",
            y=-0.2,
            xanchor="center",
            x=0.5
        )
    )
    
    st.plotly_chart(fig, use_container_width=True)
    
    # 显示具体数值
    for label, value in values.items():
        col1, col2 = st.columns([2, 1])
        with col1:
            st.write(label)
        with col2:
            st.write(f"**{value}**")


def create_metrics_grid(metrics_data: list, columns: int = 4):
    """
    创建指标网格布局
    
    Args:
        metrics_data: 指标数据列表
        columns: 列数
    """
    cols = st.columns(columns)
    
    for i, metric in enumerate(metrics_data):
        with cols[i % columns]:
            if metric["type"] == "simple":
                MetricsCard(
                    title=metric["title"],
                    value=metric["value"],
                    delta=metric.get("delta"),
                    delta_color=metric.get("delta_color", "normal"),
                    help_text=metric.get("help_text")
                )
            elif metric["type"] == "kpi":
                create_kpi_card(
                    title=metric["title"],
                    value=metric["value"],
                    target=metric.get("target"),
                    format_func=metric.get("format_func"),
                    color=metric.get("color", "#1f77b4")
                )
            elif metric["type"] == "trend":
                create_trend_card(
                    title=metric["title"],
                    current_value=metric["current_value"],
                    previous_value=metric["previous_value"],
                    format_func=metric.get("format_func"),
                    reverse_colors=metric.get("reverse_colors", False)
                )
            elif metric["type"] == "status":
                create_status_card(
                    title=metric["title"],
                    status=metric["status"],
                    description=metric.get("description"),
                    last_update=metric.get("last_update")
                )